/*
 * cxxomfort example: chinese_zodiac
 * 
 * See https://rosettacode.org/wiki/Chinese_zodiac
 * 
 */

#include <cxxomfort/cxxomfort.hpp>
//#include <cxxomfort/string_view.hpp>
#include <cxxomfort/tuple.hpp>
#include <cxxomfort/array.hpp>
#include <string>
#include <iostream>

enum Animals {
	Rat, Ox, Tiger, Rabbit, Dragon, Snake, Horse, Goat, Monkey, Rooster, Dog, Pig
};

enum Elements {
	Wood, Fire, Earth, Metal, Water
};

enum Y {
	yang, yin
};

const unsigned Y_EPOCH= 1984; // Rat, Wood, yang

typedef struct { Animals a; Elements e; Y y; } CZ;

std::ostream& operator<< (std::ostream& os, CZ const& cz) {
	using std::get;
	os<< "(";
	static const char* animals[]= {"Rat", "Ox", "Tiger", "Rabbit", "Dragon", "Snake", "Horse", "Goat", "Monkey", "Rooster", "Dog", "Pig"};
	os<< animals[cz.a]<< " ";
	static const char* elements[] = {"Wood", "Fire", "Earth", "Metal", "Water"};
	os<< elements[cz.e]<< " ";
	os<< (cz.y == 0 ? "yang" : "yin");
	os<< ")";
	return os;
}

CZ year_cz (int year) {
	using namespace std;
	static const int epoch = 1984; // rat, wood, yang
	int di= year - epoch;
	
	unsigned adiff = ((di % 12) + 12) % 12;
	unsigned ediff = ((( (di - (di<0))  / 2) % 5 ) + 5) % 5;
	int ydiff = (year - epoch) % 2;
	// cout<< "a,e : "<< adiff << " "<< ediff<< endl;
	CZ ret= { Animals(adiff), Elements(ediff), Y(ydiff) };
	return ret;
}


int main () {
    using namespace std;
    cxxomfort::output_info(); cout<< endl;
    
    //unsigned Y = 1984;
    for (unsigned i= 1984; i < 2046; ++i) {
		cout<< i<< " "<< year_cz(i)<< endl;
	}
}
